import { arrified, createTaskQueue, createStateNode, getTag } from "../Misc"

const taskQueue = createTaskQueue()
// 要执行的子任务
let subTask = null

/**
 * 获取第一个任务
 */
const getFirstTask = () => {
  /**
   * 从任务队列中获取任务
   */
  const task = taskQueue.pop()
  /**
   * 返回最外层节点的 fiber 对象
   */
  return {
    props: task.props,
    stateNode: task.dom,
    tag: "host_root",
    effects: [],
    child: null
  }
}

const reconcileChildren = (fiber, children) => {
  /**
   * children 可能是对象，也可能是数组
   * 需要把 children 转换成数组
   */
  const arrifiedChildren = arrified(children)
  
  let index = 0
  let numberOfElements = arrifiedChildren.length
  let element = null
  let newFiber = null
  let prevFiber = null

  while (index < numberOfElements) {
    element = arrifiedChildren[index]
    // 子级 fiber 对象
    newFiber = {
      type: element.type,
      props: element.props,
      tag: getTag(element),
      effects: [],
      effectTag: 'placement',
      parent: fiber
    }

    newFiber.stateNode = createStateNode(newFiber)

    // 为父级 fiber 添加子级 fiber
    if (index === 0) {
      fiber.child = newFiber
    } else {
      // 为 fiber 对象添加下一个兄弟 fiber
      prevFiber.sibling = newFiber
    }
    
    prevFiber = newFiber
    index++
  }
}

/**
 * 任务调用
 * @param {*} fiber 
 */
const excuteTask = fiber => {
  /**
   * 构建子级 fiber 对象
   */
  reconcileChildren(fiber, fiber.props.children)
  if (fiber.child) {
    return fiber.child
  }

  let currentExcutelyFiber = fiber

  while ()

  if (fiber.sibling) {
    return fiber.sibling
  }
  console.log(fiber)
}

const workLoop = deadline => {
  // 判断任务是否存在
  if (!subTask) {
    subTask = getFirstTask()
  }
  while (subTask && deadline.timeRemaining() > 1) {
    subTask = excuteTask(subTask)
  }
}

const performTask = deadline => {
  workLoop(deadline)
  /**
   * 当浏览器空闲时间过去，任务还没有执行完
   * 就需要重新等到浏览器有空闲时间的时候重新执行
   * 在重新执行前，需要判断 subTask 是否有值且任务队列中是否为空
   * 如果 subTask 有值代表之前的任务还没执行完
   * 如果 taskQueue 队列中还有任务，就继续执行队列中的任务
   */
  if (subTask || !taskQueue.isEmpty()) {
    requestIdleCallback(performTask)
  }
}

export const render = (element, dom) => {
  /**
   * 1、向任务队列中添加任务
   * 2、指定在浏览器空闲时执行任务
   */

  /**
   * 任务就是通过 vdom 对象构建 Fiber 对象
   */
  taskQueue.push({
    dom,
    props: { children: element } 
  })
  /**
   * 在任务空闲时去调用其他任务
   */
  requestIdleCallback(performTask)
}